#ifndef VENDOR_ECARX_IPLM_V1_0_IPLM_DEF_H
#define VENDOR_ECARX_IPLM_V1_0_IPLM_DEF_H

#include <cstdint>
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string>

/* REQPROD 347119 : 3 : LM IP_activity message */
#define IP_ACTIVITY_SERVICE_ID              (0xFFFF)
#define IP_ACTIVITY_OPERATION_ID            (0xFF01)
#define IP_ACTIVITY_OPERATION_TYPE          (0x06)
#define IP_ACTIVITY_DATA_TYPE               (0x01)
#define IP_ACTIVITY_LENGTH                  (0x0C) // Dec 12 byte (8 of the header bytes + 4 payload bytes)
#define IP_ACTIVITY_PROT_VER                (0x03) // REQPROD 346796 : 2 : ProtocolVersion
#define IP_ACTIVITY_PROC                    (0x0) // REQPROD 381652 : 0 : Process-flag, proc
#define IP_ACTIVITY_SENDER_HANDLE_ID_BASE   (0xFF010600) // Should add sequence number

/* Default value for IPLM Resource Group Members */
#define DEF_NUMBER_NODES_RG1                (3) // IHU, VGM, TCAM
#define DEF_NUMBER_NODES_RG2                (3) // VGM, TCAM, (DMM)
#define DEF_NUMBER_NODES_RG3                (2) // VGM, TCAM
#define DEF_NUMBER_NODES_RG4                (5) // IHU, VGM, TCAM, (DVR), (PAS)
#define DEF_NUMBER_NODES_RG5                (3) // IHU, VGM, (ASDM)
#define DEF_NUMBER_NODES_RG6                (5) // IHU, VGM, TCAM, DMM, (DIM)
#define DEF_NUMBER_NODES_RG7                (0)

typedef enum {
    NODE_IHU    = 0x0,
    NODE_VGM    = 0x01,
    NODE_TCAM   = 0x02,
    NODE_DMM    = 0x04,
    NODE_PAS    = 0x10,
    NODE_DVR    = 0x20,
    NODE_ASDM   = 0x40,
    NODE_DIM    = 0x80,
    NODE_IIM    = 0x100
} ECU_Node;

#define RG1_NODES (NODE_IHU | NODE_VGM | NODE_TCAM)
#define RG2_NODES (NODE_VGM | NODE_TCAM | NODE_DMM)
#define RG3_NODES (NODE_VGM | NODE_TCAM)
#define RG4_NODES (NODE_IHU | NODE_VGM | NODE_TCAM | NODE_PAS | NODE_DVR)
#define RG5_NODES (NODE_IHU | NODE_VGM | NODE_ASDM)
#define RG6_NODES (NODE_IHU | NODE_VGM | NODE_TCAM | NODE_DMM | NODE_DVR | NODE_PAS | NODE_DIM)
#define RG7_NODES (0)


/* Default IPLM Request Monitoring Timeout (uint: ms)*/
#define DEFAULT_REQUEST_MONITORING_TIMEOUT  (3000u)
/* Default IPLM Avtivity Broadcast Period (uint: ms)*/
#define DEFAULT_IPLM_ACTIVITY_PERIOD        (1000u)

#define DEFAULT_IPLM_STEP_PERIOD            (100u)

#define DEFAULT_VFC_TRIGGER_PERIOD          (120 * 1000)

/* IHU is belong to below Resource Group, default is Resource 1 / 4 / 5 / 6 */
#define DEFAULT_IPLM_MEMBERS                (0x72)  // (0x02 | 0x10 | 0x20 | 0x40)

/* IPLM UDP Port */
#define LOCAL_BROADCAST_PORT                (50001)
#define PEER_BROADCAST_PORT                 (50001)

/* REQPROD 347120 : 3 : LM IP_activity message structure */
#define IPLM_AVAILABLE                      (0x01)

/* Default VLAN - PCP Map */
#define DEF_VLAN2_PRIORITY                  (0)  // PCP 0
#define DEF_VLAN3_PRIORITY                  (2)  // PCP 2
#define DEF_VLAN4_PRIORITY                  (3)  // PCP 3
#define DEF_VLAN5_PRIORITY                  (5)  // PCP 5
#define DEF_VLAN6_PRIORITY                  (7)  // PCP 7
#define DEF_VLAN10_PRIORITY                 (0)  // PCP 10
#define DEF_VLAN11_PRIORITY                 (1)  // PCP 1
#define DEF_VLAN12_PRIORITY                 (0)


const std::string PEER_VGM_IP ("198.18.32.1");
const std::string PEER_TCAM_IP ("198.18.32.17");
const std::string PEER_IIM_IP ("198.18.32.20");
const std::string PEER_DVR_IP ("198.18.37.20");
const std::string PEER_ASDM_IP ("198.18.36.1");
const std::string PEER_PAS_IP ("198.18.36.96");
const std::string PEER_DMM_IP ("198.18.32.18");
const std::string PEER_DIM_IP ("198.18.32.19");
const std::string LOCAL_AP_IP ("198.18.34.15");
const std::string PEER_VP_IP ("198.18.34.1");

#define LOCAL_BROADCAST_PORT        (50001)
#define PEER_BROADCAST_PORT         (50001)

/* IPLM Default VLAN PCP is VLAN6 - PCP7 */
#define IFNAME                      "eth0.6"

// Local Test
// #define IFNAME                      "eth0"
#define IPLM_PCP                    (7)

#define IPLM_PACKET_SIZE            (20)

constexpr char kIplmNodesRG1[] = "vendor.ecarx.iplm.num_of_rg_1";
constexpr char kIplmNodesRG2[] = "vendor.ecarx.iplm.num_of_rg_2";
constexpr char kIplmNodesRG3[] = "vendor.ecarx.iplm.num_of_rg_3";
constexpr char kIplmNodesRG4[] = "vendor.ecarx.iplm.num_of_rg_4";
constexpr char kIplmNodesRG5[] = "vendor.ecarx.iplm.num_of_rg_5";
constexpr char kIplmNodesRG6[] = "vendor.ecarx.iplm.num_of_rg_6";
constexpr char kIplmNodesRG7[] = "vendor.ecarx.iplm.num_of_rg_7";

constexpr char kIplmIHUResouceGroupID[] = "vendor.ecarx.iplm.indicator";
constexpr char kIplmRMT[] = "vendor.ecarx.iplm.rmt"; // Request Monitor Timeout

constexpr char kVLAN2PCP[] = "vendor.ecarx.vlan2.pcp";
constexpr char kVLAN3PCP[] = "vendor.ecarx.vlan3.pcp";
constexpr char kVLAN4PCP[] = "vendor.ecarx.vlan4.pcp";
constexpr char kVLAN5PCP[] = "vendor.ecarx.vlan5.pcp";
constexpr char kVLAN6PCP[] = "vendor.ecarx.vlan6.pcp";
constexpr char kVLAN10PCP[] = "vendor.ecarx.vlan10.pcp";
constexpr char kVLAN11PCP[] = "vendor.ecarx.vlan11.pcp";
constexpr char kVLAN12PCP[] = "vendor.ecarx.vlan12.pcp";

typedef struct {
    uint16_t     service_id;          // 0x0000 - 0xFFFF
    uint16_t     operation_id;        // 0x0000 - 0xFFFF

    uint32_t     length;              // 0x00000008 - 0xFFFFFFFF
    uint32_t     senderHandleId;      // 32 bit (ServiceId8 | OpertionID8 | OpType8 | SeqNr8)

    uint8_t      protocol_version;    // 8bit, current version is 0x03
    uint8_t      op_type;             // 8bit
    uint8_t      payload_type;        // 0 - encoded, 1 - normal

    uint8_t      proc        : 1;     // 1 bit for proc flag(default 0x0), only applies for Request/SetRequest
    uint8_t      reserved    : 7;     // 7 bit for Reserved
} __attribute__((__packed__)) ipcp_header_t;

typedef struct {
    ipcp_header_t header;
    uint8_t action;
    uint8_t prio;
    uint16_t reserved;
} __attribute__((__packed__)) iplm_activity_t;

/* Notify Power State to VP side */
typedef enum {
    IPLM_SET_POWER_NULL = 0,
    IPLM_SET_POWER_NORMAL = 1,
    IPLM_SET_POWER_HIGH = 2,
} IPLM_Power_State;

typedef enum {
    REPORT_DTC = 2,
    CLEANUP_DTC = 3
} IPLM_DTC_VALUE;

#endif // VENDOR_ECARX_IPLM_V1_0_IPLM_DEF_H